<?php
set_include_path("../include;include");
require_once '/util/globals.php';
require_once 'Database.php';
require_once '/model/Registration.php';
require_once '/model/Event.php';
require_once '/model/Participant.php';
require_once '/model/PriceCategory.php';

/**
 * database access class for Registration
 *
 * @author Thomas Crepain <contact@thomascrepain.be>
 */
class RegistrationDAO
{
        const TABLENAME = 'registration';
        const PARTICIPANT_REGISTRATION_TABLENAME = 'participant_registration';


	/**
	 *
	 *
	 * @var Database
	 */
	private $db;

	/**
	 * Contains the group cache
	 *
	 * @var array
	 */
	private $registrationCache = array();

	/**
	 * unique instance of this class
	 * Singleton pattern
	 *
	 * @var Database
	 */
	private static $uniqueInstance;


	/**
	 * constructs the DAO
	 */
	private function __construct()
	{
		// get database
                $this->db = Database::getInstance();
	}

	/**
	 * gets instance of database
	 *
	 * @return RegistrationDAO
	 */
	public static function getInstance()
	{
		if(!isset(self::$uniqueInstance))
		{
			self::$uniqueInstance = new self();
		}

		return self::$uniqueInstance;
	}

	/**
	 * Returns the event_id
	 *
	 * @return integer
	 */
	public function getEventIdByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return (integer) $this->registrationCache[$registrationId]['event_id'];
	}

        /**
	 * Returns the email
	 *
	 * @return string
	 */
	public function getEmailByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return $this->registrationCache[$registrationId]['email'];
	}

        /**
	 * Returns the code
	 *
	 * @return string
	 */
	public function getCodeByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return $this->registrationCache[$registrationId]['code'];
	}

        /**
	 * Returns if an payment has been received
	 *
	 * @return boolean
	 */
	public function getIsPayedByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return (boolean) $this->registrationCache[$registrationId]['is_payed'];
	}

        /**
	 * Returns the name of the person responsible for the given registration
	 *
	 * @return string
	 */
	public function getResponsibleNameByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return $this->registrationCache[$registrationId]['name'];
	}

        /**
	 * Returns the total cost
	 *
	 * @return double
	 */
	public function getTotalCostByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return (double) $this->registrationCache[$registrationId]['total_cost'];
	}

        /**
	 * Returns the timestamp
	 *
	 * @return timestamp
	 */
	public function getDateTimeByRegistrationId(integer $registrationId)
	{
		// build cache
		$this->buildCache($registrationId);

		return (integer) $this->registrationCache[$registrationId]['date_time'];
	}
	
	/**
         * Returns a registration object linked to this code
         *
         * @param string $code
         * @return Registration
         */
        public function getRegistrationByCode(string $code){
            // get record from database
            $record = (array) $this->db->getRecord("SELECT r.registration_id, r.event_id, r.name, r.email, r.code, r.is_payed, r.total_cost, r.date_time
                                                FROM ".self::TABLENAME." AS r
                                                WHERE r.code = ?",
                                                array($code));

            // place record in cache
            $this->registrationCache[$record['registration_id']] = $record;

            // make an object of the record
            //$event = Event::loadEvent((integer) $record['event_id']);
            $registration = Registration::loadRegistration((integer) $record['registration_id']);
            //($event, $record['email'], $record['code'], (boolean) $record['is_payed'], (double) $record['total_cost'], (integer) $record['date_time'], $record['name']);
            //$registration->setId((integer) $record['registration_id']);

            return $registration;
        }

        /**
         * Returns a registration object linked to this code
         *
         * @param string $code
         * @return Registration
         */
        public function getRegistrationsByEvent(Event $event){
            $registrations = array();

            // get record from database
            $records = (array) $this->db->getRecords("SELECT r.registration_id, r.event_id, r.name, r.email, r.code, r.is_payed, r.total_cost, r.date_time
                                                FROM ".self::TABLENAME." AS r
                                                WHERE r.event_id = ?",
                                                array($event->getId()));

            // for every retrieved record...
            foreach ($records as $record) {
                // place record in cache
                $this->registrationCache[$record['registration_id']] = $record;

                // make an object of the record
                //$event = Event::loadEvent((integer) $record['event_id']);
                /*$registration = Registration::createNew($event, $record['email'], $record['code'], (boolean) $record['is_payed'], (double) $record['total_cost'], (integer) $record['date_time'], $record['name']);
                $registration->setId((integer) $record['registration_id']);*/
                $registration = Registration::loadRegistration((integer) $record['registration_id']);
                $registrations[] = $registration;
            }

            return $registrations;
        }

        /**
         * Links a participant to a registration with wa price category
         *
         * @param Participant $Participant
         * @param Registration $registration
         * @param PriceCategory $priceCategory
         */
        public function linkParticipantToRegistration(Participant $participant, Registration $registration, PriceCategory $priceCategory){
            $this->db->insert(self::PARTICIPANT_REGISTRATION_TABLENAME, array('participant_id' => $participant->getId(),
                                                                                'registration_id' => $registration->getId(),
                                                                                'price_category_id' => $priceCategory->getId()));
        }

        /**
	 * Build the cache for the specified id
	 *
	 * @param integer	$registrationId
	 */
	private function buildCache(integer $registrationId)
	{
		// if cache is not build
		if(!isset($this->registrationCache[$registrationId]))
		{
                    // fill cache with this registration
                    $this->registrationCache[$registrationId] = $this->db->getRecord("SELECT r.registration_id, r.event_id, r.name, r.email, r.code, r.is_payed, r.total_cost, r.date_time
                                                                            FROM ".self::TABLENAME." AS r
                                                                            WHERE r.registration_id = ?",
                                                                            array($registrationId));
		}
	}


        /**
         * Saves the given registration in the database
         *
         * @param Registration $registration
         * @return integer $id  id in database
         */
        public function save(Registration $registration){
            $id = 0;

            // is this a new registration?
            if(is_null($registration->getId())){
                $id = $this->db->insert(self::TABLENAME, array(
                        'event_id' => $registration->getEvent()->getId(),
                        'email' => $registration->getEmail(),
                        'code' => $registration->getCode(),
                        'is_payed' => $registration->isPayed(),
                        'total_cost' => $registration->getTotalCost(),
                        'date_time' => $registration->getDateTime(),
                        'name' => $registration->getResponsibleName()));
            } else {
                $id = $registration->getId();
               
                $this->db->update(self::TABLENAME, array(
                        'event_id' => $registration->getEvent()->getId(),
                        'email' => $registration->getEmail(),
                        'code' => $registration->getCode(),
                        'is_payed' => $registration->isPayed(),
                        'total_cost' => $registration->getTotalCost(),
                        'date_time' => $registration->getDateTime(),
                        'name' => $registration->getResponsibleName()));
            }

            return $id;
        }
        
        /** Sifaka's addition */
        public function saveIsPayed(Registration $registration) {
        	$this->db->update(self::TABLENAME, array(
                        'event_id' => $registration->getEvent()->getId(),
                        'is_payed' => $registration->isPayed()),
                        "registration_id=".$registration->getId());
                       
        }
}

?>